package com.dkm.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.dkm.entity.Counselor;
import com.dkm.entity.Department;
import com.dkm.entity.Role;
import com.dkm.entity.SignInLog;
import com.dkm.entity.Users;
import com.dkm.repository.CounselorRepository;
import com.dkm.repository.RoleRepository;
import com.dkm.repository.SignInLogRepository;
import com.dkm.repository.UsersRepository;
import com.dkm.service.UsersService;
import com.dkm.util.EncryptionUtil;
import com.dkm.util.ResultUtil;
@Service
public class UsersServiceImpl implements UsersService {

	//注入用户持久层
	@Autowired
	private UsersRepository usersRepository;
	
	//注入角色持久层
	@Autowired
	private RoleRepository roleRepository;
	
	//注入日志持久层
	@Autowired
	private SignInLogRepository signInLogRepository;
	
	//注入咨询师持久层
	@Autowired
	private CounselorRepository counselorRepository;
	
	@Override
	public Users findByLogin_name(String login_name) {
		
		return usersRepository.findByLogin_name(login_name);
	}

	@Override
	public Users findUsersById(String user_id) {
		// TODO Auto-generated method stub
		return usersRepository.findById(user_id).get();
	}

	@Transactional //开启事务
	@Override
	public ResultUtil updatePwd(String user_id, String oldPwd, String newPwd) {
		//根据id获取用户信息
		Optional<Users> user=usersRepository.findById(user_id);
		//修改后的用户信息
		Users u=null;
		if(user.get()!=null) {
			String login_name=user.get().getLogin_name();
			//判断旧密码是否符合
			//加密旧密码
			String eryOldPwd=EncryptionUtil.encryption(login_name, oldPwd);
			if(user.get().getPassword().equals(eryOldPwd)){
				//修改为加密后的新密码
				String eryNewPwd=EncryptionUtil.encryption(login_name, newPwd);
				user.get().setPassword(eryNewPwd);
				//执行修改
				u=usersRepository.saveAndFlush(user.get());
			}else {
				return new ResultUtil(-1, "原密码错误！", null);
			}
		}
		
		if(u!=null) {
			return new ResultUtil(0, "修改成功！", u);
		}
		return new ResultUtil(-1, "修改失败！", null);
	}

	@Override
	public Page<Users> findAllUSers(Map<String, Object> map, Pageable pageable) {
		
		return usersRepository.findAll(this.get(map), pageable);
	}

	private Specification<Users> get(Map<String, Object> map) {
		return new Specification<Users>() {

			@Override
			public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				//1、创建Predicate对象,动态sql表达式
				Predicate predicate=criteriaBuilder.conjunction();
				//2、创建一个集合，存放多个条件,动态sql表达式集合
				List<Expression<Boolean>> expressions=predicate.getExpressions();
				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Users u=(Users)map.get("user");
				System.out.println(u.toString());
				if(!StringUtils.isEmpty(u.getLogin_name())) {
					expressions.add(criteriaBuilder.like(root.get("login_name"), "%"+u.getLogin_name()+"%"));
				}
				if(!StringUtils.isEmpty(u.getIs_lockout())) {
					expressions.add(criteriaBuilder.equal(root.get("is_lockout"), u.getIs_lockout()));
				}
				try {
					if(!StringUtils.isEmpty(map.get("beginDate"))) {
						expressions.add(criteriaBuilder.greaterThanOrEqualTo(root.get("last_login_time"), sdf.parse(map.get("beginDate").toString())));
					}
					if(!StringUtils.isEmpty(map.get("endDate"))) {
						
						expressions.add(criteriaBuilder.lessThanOrEqualTo(root.get("last_login_time"), sdf.parse(map.get("endDate").toString())));
					}
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				return predicate;
			}
		};
	}

	@Transactional //开启事务
	@Override
	public ResultUtil saveAndFlushUser(Users user) {
		ResultUtil resultUtil=null;
		String operation="";
		
		if(user.getUser_id()!=null) {
			operation="修改";
			//根据id获取用户
			Users oldUser=usersRepository.getOne(user.getUser_id());
			//设置用户信息
			oldUser.setProtect_email(user.getProtect_email());
			oldUser.setProtect_phone(user.getProtect_phone());
			oldUser.setDepartment(user.getDepartment());
			//重新赋值用户
			user=oldUser;
		}else {
			operation="添加";
			//用户名不存在执行添加
			Users existsUser=usersRepository.findByLogin_name(user.getLogin_name());
			if(existsUser!=null) {
				return new ResultUtil(-1, operation+"失败，用户名已存在！", null);
			}
			//生成uuid作为新增用户的id
			String user_id=UUID.randomUUID().toString();
			user.setUser_id(user_id);
			user.setPassword_wrong_num(0);
			//使用默认头像
			user.setHead_portrait("images/user_header/default.jpg");
			user.setCreate_time(new Date());
			user.setIs_lockout("否");
			//加密密码
			String encryptionStr=EncryptionUtil.encryption(user.getLogin_name(), user.getPassword());
			user.setPassword(encryptionStr);
		}
		//保存用户信息
		Users u=usersRepository.saveAndFlush(user);
		if(u!=null) {
			resultUtil=new ResultUtil(0, operation+"成功", u);
		}else {
			resultUtil=new ResultUtil(-1, operation+"失败", null);
		}
		return resultUtil;
	}

	@Transactional //开启事务
	@Override
	public ResultUtil deleteUser(String user_id) {
		Users user=new Users();
		user.setUser_id(user_id);
		try {
			usersRepository.delete(user);
			return new ResultUtil(0, "删除成功", null);
		} catch (Exception e) {
			return new ResultUtil(-1, "删除失败", null);
		}
	}

	@Transactional //开启事务
	@Override
	public ResultUtil resetPwd(String user_id) {
		//根据用户id获取用户信息
		Users user=usersRepository.getOne(user_id);
		if(user!=null) {
			//重置密码为123456并加密
			String encrytionPwd=EncryptionUtil.encryption(user.getLogin_name(), "123456");
			//设置给用户
			user.setPassword(encrytionPwd);
			//保存用户
			Users u=usersRepository.saveAndFlush(user);
			if(u!=null) {
				return new ResultUtil(0, "重置成功,密码重置为123456", u);
			}else {
				return new ResultUtil(-1, "重置失败,用户不存在！", null);
			}
		}
		return new ResultUtil(-1, "重置失败,用户不存在！", null);
	}

	@Override
	public List<Role> getRolesByUser_id(String user_id) {
		//根据用户id获取用户信息
		Users user=usersRepository.getOne(user_id);
		if(user!=null) {
			return user.getRoles();
		}
		return null;
	}

	@Transactional //开启事务
	@Override
	public ResultUtil setRoles(String user_id, String[] roleIds) {
		//根据用户id获取用户信息
		Users user=usersRepository.getOne(user_id);
		List<Role> roles=null;
		//批量获取角色信息
		if(roleIds!=null) {
			List<String> rolesIdList=new ArrayList<String>(Arrays.asList(roleIds));
			
			roles=roleRepository.findAllById(rolesIdList);
		}
		//用于判断用户是否同时拥有咨询师和网络咨询角色
//		List<Role> distinctList=new ArrayList<Role>();
//		int role_num=0;
//		//遍历角色
//		for (Role r : roles) {
//			if(r.getRole_name().contains("咨询师")||r.getRole_name().contains("网络咨询")) {
//				distinctList.add(r);
//			}
//		}
		
		if(user!=null) {
			//获取用户的角色信息
			List<Role> hasRoles=user.getRoles();
			//遍历用户的角色
//			for (Role r : hasRoles) {
//				for (Role role : distinctList) {
//					
//				}
//				if(r.getRole_name().contains("咨询师")||r.getRole_name().contains("网络咨询")) {
//					role_num+=1;
//				}
//			}
			//如果同时拥有咨询师和网络咨询角色
//			if(role_num>=2) {
//				return new ResultUtil(-1, "设置失败,同一个用户无法拥有[咨询师]和[网络咨询师]角色！", null);
//			}
			
			//如果查到的角色信息不为空
			if(roles!=null) {
				//遍历查到的角色信息
				for (Role role : roles) {
					//如果存在于用户的角色集合中
					if(this.existsRole(role, hasRoles)) {
						//给用户移除这个角色
						hasRoles.remove(role);
						//如果设置的角色中有咨询师
						if("咨询师".equals(role.getRole_name())||"网络咨询师".equals(role.getRole_name())) {
							//获取咨询师信息
							//根据用户编号获取咨询师
							Counselor counselor=counselorRepository.getCounselorByUser_id(user.getUser_id());
							if(counselor!=null) {
								//删除咨询师
								counselorRepository.delete(counselor);
							}
						}
					}else {
						//不存在给用户添加这个角色
						hasRoles.add(role);
						//如果设置的角色中有咨询师
						if("咨询师".equals(role.getRole_name())||"网络咨询师".equals(role.getRole_name())) {
							//创建咨询师并设置信息
							Counselor counselor=new Counselor();
							counselor.setCounselor_id(UUID.randomUUID().toString());
							counselor.setCounselor_name(user.getLogin_name());
							counselor.setUser(user);
							//角色名称
							counselor.setRoleName(role.getRole_name());
							//默认最低权重为1
							counselor.setWeight(1);
							//默认不分配学生
							counselor.setIs_allot("否");
							//默认签到状态为0未签到
							counselor.setSign_in_state(0);
							//添加咨询师
							counselorRepository.saveAndFlush(counselor);
						}
					}
				}
				
				//重新给用户设置角色集合
				user.setRoles(hasRoles);
				//保存用户信息
				Users u=usersRepository.saveAndFlush(user);
				if(u!=null) {
					return new ResultUtil(0, "设置成功", u);
				}
			}
		}
		return new ResultUtil(-1, "设置失败", null);
	}
	
	/**
	 * 判断一个角色是否存在于一个角色集合中
	 * @param role
	 * @param roles
	 * @return 
	 */
	private boolean existsRole(Role role,List<Role> roles) {
		//遍历集合
		for(Role item:roles) {
			if(item.getRole_id().equals(role.getRole_id())) {
				//存在
				return true;
			}
		}
		return false;
	}

	@Transactional //开启事务
	@Override
	public ResultUtil locktopic(String user_id, String is_lockout) {
		//根据用户id获取用户信息
		Users user=usersRepository.getOne(user_id);
		String operation="";
		//如果查不到用户信息
		if(user==null) {
			return new ResultUtil(-1, "操作失败", null);
		}
		
		if("是".equals(is_lockout)) {
			//锁定
			operation="锁定";
			//设置锁定信息
			user.setIs_lockout(is_lockout);
			user.setLock_time(new Date());
		}else {
			//解锁
			operation="解锁";
			user.setIs_lockout(is_lockout);
			user.setLock_time(null);
		}
		ResultUtil resultUtil=null;
		
		Users u=usersRepository.saveAndFlush(user);
		if(u!=null) {
			resultUtil=new ResultUtil(0, operation+"成功！", u);
		}else {
			resultUtil=new ResultUtil(-1, operation+"失败！", u);
		}
		return resultUtil;
	}

	@Override
	public ResultUtil getDepartmentByUser_id(String current_user_id) {
		//根据id获取用户信息
		Users user=usersRepository.findById(current_user_id).get();
		if(user!=null) {
			if(user.getDepartment()!=null) {
				return new ResultUtil(0, "部门数据获取成功！", user.getDepartment());
			}
		}
		return new ResultUtil(-1, "部门数据获取失败！", null);
	}
	
	@Transactional //开启事务
	@Override
	public ResultUtil signIn(String current_user_id) {
		System.out.println("=============签到===========");
		SimpleDateFormat timestampsdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat datesdf=new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
		//获取当前时间
		Date date=new Date();
		try {
		//获取该用户今天的签到信息
		String d=datesdf.format(date);
		SignInLog sl=signInLogRepository.getSignInLogByUser_idAndDate(current_user_id,timestampsdf.parse(d+" 00:00:00") ,timestampsdf.parse(d+" 23:59:59"));
		//如果日志信息不为空
		if(sl!=null) {
			return new ResultUtil(-1, "签到失败,今天已完成签到！", sl);
		}
		//根据用户id获取用户信息
		Users user=usersRepository.findById(current_user_id).get();
		if(user!=null) {
			
				//获取部门信息
				Department department=user.getDepartment();
				System.out.println(sdf.format(new Date()));
				//获取部门签到时间和缓冲时间
				Date beginSignIn= sdf.parse(department.getSign_in_time());
				int buffer_time=department.getBuffer_time();
				//计算签到时间区间
				Date endSignIn=new Date(beginSignIn.getTime()+buffer_time*60*60*1000);
				beginSignIn=new Date(beginSignIn.getTime()-1000);
				System.out.println("beginSignIn>"+beginSignIn);
				System.out.println("endSignIn>"+endSignIn);
				System.out.println("curTime"+date);
				Date curTime=sdf.parse(sdf.format(date));
				if(beginSignIn.before(curTime)&&endSignIn.after(curTime)) {
					
					//创建日志信息
					String uuid=UUID.randomUUID().toString();
					SignInLog signInLog=new SignInLog(uuid, current_user_id, user.getLogin_name(), date, 1, null);
					//生成日志
					SignInLog s=signInLogRepository.saveAndFlush(signInLog);
					
					if(s!=null) {
						//签到成功
						
						//遍该用户的角色集合
						for (Role role : user.getRoles()) {
							//如果该用户拥有咨询师角色
							if("咨询师".equals(role.getRole_name())) {
								//获取咨询师信息
								Counselor counselor=counselorRepository.getCounselorByUser_id(current_user_id);
								//修改签到状态(0:未签到，1:签到)
								counselor.setSign_in_state(1);
								//保存咨询师信息
								counselorRepository.saveAndFlush(counselor);
							}
							if("网络咨询师".equals(role.getRole_name())) {
								//获取网络咨询师信息
								Counselor netCounselor=counselorRepository.getNetCounselorByUser_id(current_user_id);
								//修改签到状态(0:未签到，1:签到)
								netCounselor.setSign_in_state(1);
								//保存网络咨询师信息
								counselorRepository.saveAndFlush(netCounselor);
							}
						}
						
						System.out.println("签到成功");
						return new ResultUtil(0, "签到成功", s);
					}
				}else {
					return new ResultUtil(-1, "签到失败,不在签到时间内！", null);
				}
			
		}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new ResultUtil(-1, "签到失败！", null);
	}

	@Override
	public ResultUtil signOut(String current_user_id) {
		System.out.println("=============签到===========");
		SimpleDateFormat timestampsdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat datesdf=new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sdf=new SimpleDateFormat("HH:mm");
		//获取当前时间
		Date date=new Date();
		try {
		//获取该用户今天的签到信息
		String d=datesdf.format(date);
		SignInLog sl=signInLogRepository.getSignInLogByUser_idAndDate(current_user_id,timestampsdf.parse(d+" 00:00:00") ,timestampsdf.parse(d+" 23:59:59"));
		//如果日志信息为空
		if(sl==null) {
			return new ResultUtil(-1, "今天还未签到", null);
		}
		//根据用户id获取用户信息
		Users user=usersRepository.findById(current_user_id).get();
		if(user!=null) {
			
				//获取部门信息
				Department department=user.getDepartment();
				System.out.println(sdf.format(new Date()));
				//获取部门签退时间和缓冲时间
				Date beginSignOut= sdf.parse(department.getSign_out_time());
				int buffer_time=department.getBuffer_time();
				//计算签退时间区间
				Date endSignOut=new Date(beginSignOut.getTime()+buffer_time*60*60*1000);
				beginSignOut=new Date(beginSignOut.getTime()-1000);
				System.out.println("beginSignIn>"+beginSignOut);
				System.out.println("endSignIn>"+endSignOut);
				System.out.println("curTime"+date);
				Date curTime=sdf.parse(sdf.format(date));
				if(beginSignOut.before(curTime)&&endSignOut.after(curTime)) {
					
					//创建日志信息
					//String uuid=UUID.randomUUID().toString();
					//SignInLog signInLog=new SignInLog(uuid, current_user_id, date, 1, null);
					//如果签退时间不为空
					if(sl.getSign_out_time()!=null) {
						return new ResultUtil(-1, "签退失败,今天已完成签退！", null);
					}
					sl.setSign_out_time(new Date());
					sl.setSign_in_status(2);
					SignInLog s=signInLogRepository.saveAndFlush(sl);
					
					if(s!=null) {
						//签退成功
						
						//遍该用户的角色集合
						for (Role role : user.getRoles()) {
							//如果该用户拥有咨询师角色
							if("咨询师".equals(role.getRole_name())) {
								//获取咨询师信息
								Counselor counselor=counselorRepository.getCounselorByUser_id(current_user_id);
								//修改签到状态(0:未签到，1:签到)
								counselor.setSign_in_state(0);
								//保存咨询师信息
								counselorRepository.saveAndFlush(counselor);
							}
							if("网络咨询师".equals(role.getRole_name())) {
								//获取网络咨询师信息
								Counselor netCounselor=counselorRepository.getNetCounselorByUser_id(current_user_id);
								//修改签到状态(0:未签到，1:签到)
								netCounselor.setSign_in_state(1);
								//保存网络咨询师信息
								counselorRepository.saveAndFlush(netCounselor);
							}
						}
						System.out.println("签退成功");
						return new ResultUtil(0, "签退成功", s);
					}
				}else {
					return new ResultUtil(-1, "签退失败,不在签退时间内！", null);
				}
			
		}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new ResultUtil(-1, "签退失败！", null);
	}

	@Override
	public List<Users> getAllUsers() {
		
		return usersRepository.findAll();
	}

	@Transactional //开启事务
	@Override
	public ResultUtil updateUserHead_portrait(String user_id, String head_portrait) {
		//获取用户信息
		Users user=usersRepository.findById(user_id).get();
		if(user==null) {
			return new ResultUtil(-1, "用户数据异常！", null);
		}
		//修改头像
		user.setHead_portrait(head_portrait);
		
		//保存用户信息
		Users u1=usersRepository.saveAndFlush(user);
		if(u1!=null) {
			return new ResultUtil(0, "修改成功", u1);
		}
		return new ResultUtil(-1, "修改失败", null);
	}

	@Override
	public Users getUserById(String user_id) {
		return usersRepository.findById(user_id).get();
	}


}
